package com.chenyun.boot.web.config;

import org.apache.http.client.HttpClient;
import org.apache.http.client.config.RequestConfig;
import org.apache.http.config.Registry;
import org.apache.http.config.RegistryBuilder;
import org.apache.http.conn.socket.ConnectionSocketFactory;
import org.apache.http.conn.socket.PlainConnectionSocketFactory;
import org.apache.http.conn.ssl.SSLConnectionSocketFactory;
import org.apache.http.impl.client.HttpClientBuilder;
import org.apache.http.impl.conn.PoolingHttpClientConnectionManager;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.boot.web.servlet.FilterRegistrationBean;
import org.springframework.cloud.client.loadbalancer.LoadBalanced;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.client.HttpComponentsClientHttpRequestFactory;
import org.springframework.web.client.RestTemplate;


/**
 * @author Lonni
 * @Description:
 * @date 2021/6/3011:33
 */
@Configuration
public class WebConfiguration {

    @Autowired
    private RestTemplatePoolProperties restTemplatePoolProperties;

    @Bean
    @LoadBalanced
    public RestTemplate restTemplate() {
//        HttpComponentsClientHttpRequestFactory httpRequestFactory = new HttpComponentsClientHttpRequestFactory();
//        httpRequestFactory.setConnectionRequestTimeout(30 * 1000);
//        httpRequestFactory.setConnectTimeout(30 * 3000);
//        httpRequestFactory.setReadTimeout(30 * 3000);
//        return new RestTemplate(httpRequestFactory);

        //设置为池化链接 ,避免每次都创建
        return new RestTemplate(new HttpComponentsClientHttpRequestFactory(httpClient()));
    }

    @Bean
    public HttpClient httpClient() {
        Registry<ConnectionSocketFactory> registry = RegistryBuilder.<ConnectionSocketFactory>create()
                .register("http", PlainConnectionSocketFactory.getSocketFactory())
                .register("https", SSLConnectionSocketFactory.getSocketFactory())
                .build();
        PoolingHttpClientConnectionManager connectionManager = new PoolingHttpClientConnectionManager(registry);
        //设置整个连接池最大连接数 根据自己的场景决定
        connectionManager.setMaxTotal(restTemplatePoolProperties.getMaxPool());
        //路由是对maxTotal的细分 即链接到同一个主机最高的并发是多少,最终不能超过MaxTotal
        connectionManager.setDefaultMaxPerRoute(100);
        RequestConfig requestConfig = RequestConfig.custom()
                .setSocketTimeout(restTemplatePoolProperties.getSocketTimeout()) //服务器返回数据(response)的时间，超过该时间抛出read timeout
                .setConnectTimeout(restTemplatePoolProperties.getConnectTimeout())//连接上服务器(握手成功)的时间，超出该时间抛出connect timeout
                .setConnectionRequestTimeout(restTemplatePoolProperties.getRequestTimeout())//从连接池中获取连接的超时时间，超过该时间未拿到可用连接，会抛出org.apache.http.conn.ConnectionPoolTimeoutException: Timeout waiting for connection from pool
                .build();
        return HttpClientBuilder.create()
                .setDefaultRequestConfig(requestConfig)
                .setConnectionManager(connectionManager)
                .build();
    }


    /**
     * 注册演示环境过滤器
     *
     * @return
     */
    @Bean
    @ConditionalOnProperty(value = "chenyun.demo", havingValue = "true")
    public FilterRegistrationBean<DemoOncePerRequestFilter> demoOncePerRequestFilter() {
        FilterRegistrationBean<DemoOncePerRequestFilter> registrationBean = new FilterRegistrationBean<>();
        registrationBean.setFilter(new DemoOncePerRequestFilter());
        registrationBean.setName("demoOncePerRequestFilter");
        registrationBean.setOrder(Integer.MAX_VALUE);
        return registrationBean;
    }

    /**
     * 注册文件处理过滤器
     *
     * @return
     */
//    @Bean
//    public FilterRegistrationBean<InputStreamBodyFilter> inputStreamBodyFilter() {
//        FilterRegistrationBean<InputStreamBodyFilter> registrationBean = new FilterRegistrationBean<>();
//        registrationBean.setFilter(new InputStreamBodyFilter());
//        registrationBean.setName("inputStreamBodyFilter");
//        registrationBean.setOrder(Integer.MAX_VALUE + 10);
//        return registrationBean;
//    }
}
